#include<stdio.h>
#include<pthread.h>


int counter=0;
//定义条件变量------顾客、厨师
pthread_mutex_t mutex;
pthread_cond_t cond_cus,cond_cook;

void* Customer(void* arg)
{
  pthread_mutex_t* mutex=(pthread_mutex_t*)arg;
  while(1){
    //首先进行加锁
    pthread_mutex_lock(mutex);
    //其次判断是否有饭
    while(counter<=0){
      //柜台上没有饭----------阻塞顾客---->阻塞/休眠 (原子性)
      pthread_cond_wait(&cond_cus,mutex);
    }
    //有饭----吃饭
    printf("柜台上有饭，饭很好吃，再来一碗！\n");
    counter--;
    //唤醒厨师来做饭
    pthread_cond_signal(&cond_cook);
    //进行解锁
    pthread_mutex_unlock(mutex);
  }

  return NULL;
}

void* Cook(void* arg)
{
  pthread_mutex_t* mutex=(pthread_mutex_t*)arg;
  while(1){
    //首先进行加锁
    pthread_mutex_lock(mutex);
    //其次判断柜台上是否有饭
    while(counter>0){
      //有饭----不需要做饭，阻塞
      pthread_cond_wait(&cond_cook,mutex);
    }
    //没有饭，需要厨师做饭
    printf("饭做好了，快来吃饭！\n");
    counter++;
    //唤醒顾客来吃饭
    pthread_cond_signal(&cond_cus);
    //解锁
    pthread_mutex_unlock(mutex);
  }
  return NULL;
}
int main()
{
  //定义互斥锁并进行初始化操作
  pthread_mutex_init(&mutex,NULL);

  pthread_cond_init(&cond_cus,NULL);
  pthread_cond_init(&cond_cook,NULL);

  //定义多个线程
  int ret;
  pthread_t cus_tid[3],cook_tid[3];
  int i=0;
  for(;i<3;++i){
    ret = pthread_create(&cus_tid[i],NULL,Customer,&mutex);
    if(ret!=0){
      perror("pthread_create error!\n");
      return -1;
    }
  }

  for(i=0;i<3;++i){
    ret = pthread_create(&cook_tid[i],NULL,Cook,&mutex);
    if(ret!=0){
      perror("pthread_create error!\n");
      return -1;
    }
  }

  //等待线程
  pthread_join(cus_tid[0],NULL);
  pthread_join(cook_tid[0],NULL);

  //释放互斥锁,释放条件变量
  pthread_mutex_destroy(&mutex);
  pthread_cond_destroy(&cond_cus);
  pthread_cond_destroy(&cond_cook);
  return 0;
}
